/*************************************************************************
 * @file: kef.cpp
 * @date: 01/04/2012
 * TOPOL v1_0 - (c)copyright 2012 TEC/UFF
 *************************************************************************
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 ************************************************************************/

// includes
//----------
#include "kef.h"
#include <iostream>
#include "../hedmodel.h"
#include "../entity/solid.h"
#include "../entity/face.h"
#include "../entity/loop.h"
#include "../entity/vertex.h"
#include "../entity/halfedge.h"
#include "../entity/edge.h"
#include "../entity/ipoint.h"



///////////////////////////////////////////////////
///  Constructor and Destructor Implementation  ///
///////////////////////////////////////////////////

//-------------------------------------------------------------------------
KEF::KEF( HEDModel& _model, int _s, int _v1, int _v2, int _fno )
: m_he1( NULL )
, m_he2( NULL )
{
  Solid* s = NULL;
  Face* f = NULL;
  HalfEdge* he = NULL;
  if( (s = _model.getSolid(_s)) == NULL )
  {
    std::cout << "kef: solid " << _s << " not found. \n";
    //return(ERROR);
  }
  if( (f = _model.fface(s,_fno)) == NULL )
  {
    std::cout << "kef: face " << _fno << " not found in solid " << _s << ". \n";
    //return(ERROR);
  }
  if( (he = _model.fhe(f,_v1,_v2)) == NULL )
  {
    if( (he = _model.fhe(f,_v2,_v1)) == NULL )
    {
      std::cout << "kef: edge " << _v1 << " - " << _v2 << " not found in face " << _fno << ". \n";
      //return(ERROR);
    }
  }
  m_he1 = he;
  m_he2 = he->mate();
}
//-------------------------------------------------------------------------


//-------------------------------------------------------------------------
KEF::KEF( HalfEdge* _he1, HalfEdge* _he2 )
: m_he1( _he1 )
, m_he2( _he2 )
{
}
//-------------------------------------------------------------------------


///////////////////////////////////////
///  PUBLIC Methods Implementation  ///
///////////////////////////////////////

//-------------------------------------------------------------------------
void
KEF::execute()
{
  std::cout << "\nKEF::execute() \n";

  Face *f1, *f2;
  Loop *l, *l1, *l2;
  register HalfEdge *he;

  Solid *s;
  s = m_he1->getLoop()->getFace()->getSolid();
  l1 = m_he1->getLoop();
  f1 = l1->getFace();
  l2 = m_he2->getLoop();
  f2 = l2->getFace();

  while(l = f2->getFloops())
  {
    //delete l;
    if( l->getPrevLoop() )
      l->getPrevLoop()->setNxt( l->getNextl() );
    if( l->getNextl() )
      l->getNextl()->setPrv( l->getPrevLoop() );
    if(l == f2->getFloops() )
      f2->setLoop( l->getNextl() );
    //l = new Loop(f1);
    l->setNxt( f1->getFloops() );
    l->setPrv( NULL );
    if( f1->getFloops() )
    {
      f1->getFloops()->setPrv( l );
    }
    f1->setLoop( l );
    l->setLFace( f1 );
  }

  he = l2->getLedg();
  do
  {
    he->setWloop( l1 );
  }
  while( (he = he->getNxt()) != l2->getLedg() );

  m_he1->getPrv()->setNxt( m_he2 );
  m_he2->getPrv()->setNxt( m_he1 );
  he = m_he2->getPrv();
  m_he2->setPrv( m_he1->getPrv() );
  m_he1->setPrv( he );

  m_he2->delhe();
  m_he1->delhe();

  m_he2->getVtx()->setVedge( m_he1->getNxt() );
  if( !m_he2->getVtx()->getVEdge()->getEdg() )
    m_he2->getVtx()->setVedge( NULL );
  m_he1->getVtx()->setVedge( m_he2->getNxt() );
  if( !m_he1->getVtx()->getVEdge()->getEdg() )
    m_he1->getVtx()->setVedge( NULL );

  l1->setLedg( m_he1->getNxt() );

  l2->setLFace( f1 );
  delete l2;
  delete f2;
  delete m_he2->getEdg();

  f1->setSurface();

}
//-------------------------------------------------------------------------

//-------------------------------------------------------------------------
void
KEF::unExecute()
{
  std::cout << "\nKEF::unExecute() NOT IMPLEMENTED!\n";
}
//-------------------------------------------------------------------------







